/*
 * AltHexagonMap.fx
 *
 * Created on Sep 5, 2009, 3:10:34 PM
 */

package fxbattle.fxgui;

/**
 * @author spina
 */

import javafx.scene.CustomNode;
import javafx.scene.Node;
import javafx.scene.Group;
import java.lang.Math;
import fxbattle.client.model.BattleMap;
import javafx.scene.transform.Transform;
import fxbattle.client.model.Direction;
import javafx.scene.paint.Color;
import javafx.scene.effect.ColorAdjust;
import edu.stsci.CoSI.Propagator;
import fxbattle.client.model.FxConstraint;
import fxbattle.client.model.Player;
import fxbattle.fxgui.FlowArrow;
import fxbattle.client.model.Location;
import fxbattle.client.model.BoundaryHex;
import javafx.util.Sequences;

def sin60 = Math.sin(Math.toRadians(60));
def cos60 = Math.cos(Math.toRadians(60));
def baseStroke = 8;
def normalStroke = 2;
def transparent = Color{ blue: 0 green: 0 red: 0 opacity: 0 }

public class HexagonMap extends CustomNode {
    public var map: BattleMap;
    public var player: Player;
    var playerColor: Color;
    var hexes: Node[] = [];
    postinit {
        Propagator.addConstraint(HexConstraint{
            public override function run() {
                playerColor = toFxColor(player.getColor());
            }});
        Propagator.addConstraint(HexConstraint{
                public override function run() {
                    for(row in [map.getMinX() .. map.getMaxX()]){
                        for(col in [map.getMinY() .. map.getMaxY()]){
                            if( createdNodes.add(Location.getLocation(row, col)) ){
                                //println("Making node for {row}, {col}");
                                insertNewHexNode(row, col);
                            }
                        }
                    }
                }
            });
    }

    var currentFlowArrowDirection = Direction.NORTH;
    var currentFlowArrowVisible = true;
    var currentFlowArrowLocation = Location.getLocation(0, 0);
    def currentFlowArrow = FlowArrow {
        length: GameHexagon.arrowSize
        stroke: bind playerColor;
        effect: ColorAdjust {
                brightness: .2
            }
        visible: bind currentFlowArrowVisible
        transforms: bind [
                          Transform.translate(75, 75),
                          GameHexagon.createTranslation(currentFlowArrowLocation.getX(),
                                                        currentFlowArrowLocation.getY()),
                          Transform.rotate(currentFlowArrowDirection.angle() - 90, 0, 0)]
        };

    def createdNodes = new java.util.HashSet();

    function insertNewHexNode(row: Integer, col: Integer) {
                var showThisHex = true on replace {
                        if(showThisHex){
                            insert hex into hexes;
                        } else {
                            delete hex from hexes;
                        }
                    };
                def hex = GameHexagon {
                    playerColor: bind playerColor
                    visible: showThisHex
                    transforms: [GameHexagon.createTranslation(row, col), Transform.translate(75, 75)]
                    elevationPercent: 1 - map.getHex(row, col).getElevationAsPercentage()

                    public override function mousePressedOnDir(dir: Direction){
                        toggleFlowPath(row, col, dir);
                    }
                    override public function mouseEnteredDir(dir: Direction): Void{
                        currentFlowArrowLocation = Location.getLocation(row, col);
                        currentFlowArrowDirection = dir;
                        currentFlowArrowVisible = true;
                        //currentFlowArrow = (allFlowArrows.get(Location.getLocation(row, col)) as java.util.Map).get(dir) as FlowArrow;
                    }
                    override public function mouseExitedDir(dir: Direction): Void{
                        if(currentFlowArrowLocation == Location.getLocation(row, col)){
                            currentFlowArrowVisible = false;
                        }
                    }

                };
                // Proven to run once per click.
                Propagator.addConstraint(HexConstraint{
                    public override function run() {
                        var curHex = map.getHex(row, col);
                        hex.armyColor = toFxColor(curHex.getControllingArmy().getOwner().getColor());
                        hex.armySize = curHex.getControllingArmy().sizeAsPercentage();
                        showThisHex = not (curHex instanceof BoundaryHex);
                        hex.isBase = curHex.isBase();
                    }
                });
                // Proven to run once per click.
                Propagator.addConstraint(HexConstraint{
                    public override function run() {
                        var curHex = map.getHex(row, col);
                        for(lDir in Direction.values()){
                            if(curHex.isFlowPathActive(lDir)){
                                if(Sequences.indexOf(hex.activeDirections, lDir) == -1){
                                    insert lDir into hex.activeDirections;
                                }
                            } else {
                                delete lDir from hex.activeDirections;
                            }
                        }
                    }
                });

                insert hex into hexes;
    }



    public override function create(): Node {
        def hexgroup = Group{
            content: bind hexes
            public override function toString(): String{"Hexagon Map"}
        }
        def everything = Group{
                content: [hexgroup, currentFlowArrow]
            }
        //return hexgroup;
	    return everything;
    }

    public function toggleFlowPath(row: Integer, col: Integer, dir: Direction){ }


}

class HexConstraint extends FxConstraint {
    public override function run() {}
}

public function toFxColor(c: java.awt.Color) {
    return Color {
        red: c.getRed()/255.0
        blue: c.getBlue()/255.0
        green: c.getGreen()/255.0
        opacity: c.getAlpha()/255.0
    }
}